package com.sensetime.jv.filter;

import com.fasterxml.jackson.core.type.TypeReference;
import com.sensetime.jv.util.JsonUtils;
import com.sensetime.jv.util.UserInfoUtils;
import jakarta.servlet.FilterChain;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.apache.logging.log4j.ThreadContext;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;
import org.springframework.web.filter.OncePerRequestFilter;

import java.io.IOException;

import static com.sensetime.jv.constants.CustomConstant.*;

/**
 * JWT 认证过滤器：从请求头中提取 Token，验证有效性，并设置用户认证信息
 */
@Component
@Slf4j
public class CustomFilter extends OncePerRequestFilter {

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain chain) throws IOException, ServletException {

        // 打印请求头中的requestId
        // 如果请求头中有requestId，则将其放入MDC中
        if(!ObjectUtils.isEmpty(request.getHeader(REQUEST_ID_HEADER))){
            ThreadContext.put(REQUEST_ID, request.getHeader(REQUEST_ID_HEADER));
        }
        // 获取请求头中的userInfo
        String userHeader = request.getHeader(USERINFO_HEADER);
        // 如果请求头中有userInfo，则将其缓存
        if (userHeader != null) {
            UserInfoUtils.cacheUserInfo(JsonUtils.readValue(userHeader, new TypeReference<>() {}));
        }
        // 打印MDC中的requestId
        try {
            // 3. 全部通过，把认证信息放进上下文
            chain.doFilter(request, response);
        } finally {
            // 清除缓存中的userInfo
            UserInfoUtils.clearUserInfo();
        }
    }
}